%%--------------------------------------------------------------------
%% Author: <vjache>
%% Created: 12.06.2009
%% Description: TODO: Add description to merge_sort
%%--------------------------------------------------------------------
-module(iter_counter).

%%--------------------------------------------------------------------
%% Include files
%%--------------------------------------------------------------------
-include("../include/iter.hrl").
%%--------------------------------------------------------------------
%% Exported Functions
%%--------------------------------------------------------------------
-export([
		 new/3,
		 new_progress_observer/3,
		 open/1,
		 next/1,
		 close/1,
		 test/1,
		 test1/1
		 ]).

%%--------------------------------------------------------------------
%% API Functions
%%--------------------------------------------------------------------

new(BaseIter,CounterFun,CounterState0) 
	when is_record(BaseIter, iter) and is_function(CounterFun, 2) ->
	iter:from_module(
		?MODULE, 
		{BaseIter, CounterFun, CounterState0}).

new_progress_observer(BaseIter,Page,CallbackFun) when is_record(BaseIter, iter) andalso is_function(CallbackFun, 2) andalso is_integer(Page) ->
	Counter0=1,
	new(BaseIter,
		fun	(?EOF,Counter)->
				 CallbackFun(finish,Counter);
			(_Item,Counter)->
				case Counter rem Page of
					0 when Counter>0 ->
						CallbackFun(progress,Counter);
					_ when Counter==Counter0 ->
						CallbackFun(start,Counter);
					_ ->
						ok
				end,
				Counter+1
		end, Counter0).
	

open({Iter,CounterFun,CounterState0}) ->
	State=iter:open(Iter),
	{State,CounterFun,CounterState0}.

next({State,CounterFun,CounterState0}) ->
	{NewState,Item}=iter:next(State),
	CounterState1=CounterFun(Item,CounterState0),
	{{NewState,CounterFun,CounterState1},Item}.

close({State,_CounterFun,_CounterState}) ->
	ok=iter:close(State).

%%--------------------------------------------------------------------
%% Test Functions
%%--------------------------------------------------------------------

test(L) ->
	new(iter:from_list(L),
		fun	(?EOF,Counter)->
				 io:format("totaly ~p~n",[Counter]);
			(_Item,Counter)->
				case Counter rem 100 of
					0 when Counter>0 ->
						io:format("progress ~p~n",[Counter]);
					_ ->
						ok
				end,
				Counter+1
		end, 0).
test1(L) ->
	new_progress_observer(iter:from_list(L),100,
						  fun(start,_Count)->
								  io:format("start~n");
							 (progress,Count)->
								  io:format("progress ~p~n",[Count]);
							 (finish,Count)->
								  io:format("finish with ~p~n",[Count])
						  end).


%%--------------------------------------------------------------------
%% Local Functions
%%--------------------------------------------------------------------